<?php
/**
 * Library of functions and constants for basiclti module
 *
 * It contains all internal functions for basiclti module
 *
 * @author Jordi Piguillem
 *
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package basiclti
 *
 */


/**
 * Prints an Simple LTI activity
 *
 * $param int $basicltiid 		Simple LTI activity id
 */
function basiclti_view($basicltiid){
	global $DB;

	$instance = $DB->get_record('basiclti', array('id' => $basicltiid));

	$params = basiclti_get_request_params($instance);

	$response = basiclti_request($instance->toolurl, $instance->password,$params);
	basiclti_print_response($basicltiid, $response);
}

/**
 * This functions makes the requests to the server
 *
 * @param string $url				Server URL
 * @param string $password			Remote Tool password
 * @param string $params			Request params
 *
 * @return string		Contains server response
 *
 */
function basiclti_request($url, $password, $params){
	global $USER, $COURSE;

	$post = curl_init($url);
	curl_setopt($post, CURLOPT_HEADER, 1);
	curl_setopt($post, CURLOPT_POST, 1);
	curl_setopt($post, CURLOPT_POSTFIELDS, $params);
	curl_setopt($post, CURLOPT_RETURNTRANSFER, 1);

	$response = curl_exec($post);

	curl_close($post);

	return $response;
}

/**
 * This functions proceses the response and prints it
 *
 * @param $basicltiid			Simplelti activity id
 * @param $response				Server response
 *
 */
function basiclti_print_response($basicltiid, $response){
	global $DB;

	$instance = $DB->get_record('basiclti', array('id' => $basicltiid));

	$pattern = '/<status>(?<status>\w+)<\/status>/';
	if (preg_match($pattern, $response, $launchresponse)){
		if ($launchresponse['status'] == 'success'){

			$pattern = '/<type>(?<type>\w+)<\/type>/';
			preg_match($pattern, $response, $launchresponse);
			switch ($launchresponse['type']){
				case 'widget':
					$pattern = '/<widget>(.*?)<\/widget>/sm';
					preg_match($pattern, $response, $launchresponse);
					$response = basiclti_format_widget($launchresponse[1]);
					break;
				case 'iFrame':
					$pattern = '/<launchUrl>(.*?)<\/launchUrl>/';
					preg_match($pattern, $response, $launchresponse);
					$response = basiclti_format_iFrame($launchresponse[1],
						$instance->preferwidth, $instance->preferheight);
					break;
				case 'post':
					$pattern = '/<launchUrl>(.*?)<\/launchUrl>/';
					preg_match($pattern, $response, $launchresponse);
					$response = basiclti_format_post($basicltiid, $launchresponse[1],
						$instance->preferwidth, $instance->preferheight);
					break;
				default:
					notice("Unknwon type");
					break;
			}

		} else {
			notice("Connection error");
		}

	}

	echo $response;
}

/**
 * This function generates the params for the request
 *
 * @param StdClass $basiclti		Simplelti activity instance
 *
 * @return string 					Contains all params need for request
 *
 * @TODO: Create a generic function. Useful for filter (or block)
 */
function basiclti_get_request_params($basiclti){
	global $USER, $COURSE;

	$targets = basiclti_get_launch_targets($basiclti);

	$context = get_context_instance(CONTEXT_MODULE, $basiclti->id);
	$role = basiclti_get_ims_role($USER, $context);

	$date = basiclti_get_date();
	$nonce = basiclti_nonce();
	$digest = basiclti_digest($nonce, $date, $basiclti->password);
	$params =
		'action='.urlencode('launchresolve') . '&' .
		'sec_nonce='.urlencode($nonce) . '&' .
		'sec_created='.urlencode($date) . '&' .
		'sec_digest='.urlencode($digest) . '&' .
		'user_id='.urlencode($USER->id) . '&' .
		'user_role='.urlencode($role) . '&' .
		'user_displayid='.urlencode($USER->username) . '&' .
		'course_id='.urlencode($COURSE->id) . '&' .
		'course_name='.urlencode($COURSE->shortname) . '&' .
		'launch_width='.$basiclti->preferwidth . '&' .
		'launch_height='.$basiclti->preferheight . '&' .
		'launch_targets='.urlencode($targets);

	if (!empty($basiclti->resourceurl))
	$params = $params. '&' .'launch_resource_id='.urlencode($basiclti->resourceurl);

	return $params;
}

/**
 * Returns the launch targets of a basiclti activity
 *
 * @param StdClass $basiclti		Simplelti activity instance
 *
 * @return	string					comma separated targets
 */
function basiclti_get_launch_targets($basiclti){

	$targets = "iframe,post";

	if ($basiclti->preferwidget){
		$targets = "widget,".$targets;
	}
	return $targets;

}

/**
 * This function returns a formated widget
 *
 *  @param string $wigdet		widget from curl response
 *
 *  @return string				formated widget, ready to print
 *
 */
function basiclti_format_widget($widget){
	$widget = html_entity_decode($widget);

	return $widget;
}

/**
 * This function returns a formated iframe
 *
 *  @param string $url		url from curl response
 *  @param int $height		activity prefered height
 *
 *  @return string			formated iframe, ready to print
 *
 */
function basiclti_format_iframe($url, $width, $height){

	return '
	<iframe src="'.$url.'"
      height="'.$height.'" width="'.$width.'" scrolling="auto" frameborder="1" transparency>
      <p>Error</p>
    </iframe>';
}

/**
 * This function returns a formated post
 *
 *  @param string $url		url from curl response
 *
 *  @return string			formated post, ready to print
 *
 */
function basiclti_format_post($basicltiid, $url, $width, $height){

	$url = '<iframe src="post.php?id='.$basicltiid.'&amp;url='.urlencode($url).'
      height="'.$height.'" width="'.$width.'" scrolling="auto" frameborder="1" transparency>
      <p>Error</p>
    </iframe>';
	return $url;
}

/**
 * This functions returns GMT time in ISO8601 format
 *
 * i.e.:2008-07-23T13:29:07Z
 *
 * @return string			GMT time in ISO8601 format
 */
function basiclti_get_date(){
	return gmdate("Y-m-d\TH:i:s\Z", time());

}

/**
 * Generates a nonce for remote connection
 *
 * @return string			Contains a nonce for connection
 */
function basiclti_nonce(){
	return base64_encode(mt_rand().'-'.mt_rand()/time().'\\'.mt_rand());
}

/**
 * Creates a digest for remote connection
 *
 * @param string $nonce			A nonce
 * @param string $date			Time correctly formated
 * @param string $password		Remote tool password
 *
 * @return string				Generated digest
 */
function basiclti_digest($nonce, $date, $password){
	$concat = $nonce . $date . $password;
	$sha1 = sha1($concat,true);
	return base64_encode($sha1);
}

/**
 * Returns the IMS user role in a given context
 *
 * This function queries Moodle for an user role and
 * returns the correspondant IMS role
 *
 * @param StdClass $user			Moodle user instance
 * @param StdClass $context			Moodle context
 *
 * @return string					IMS Role
 *
 */
function basiclti_get_ims_role($user, $context){

	$roles = get_user_roles($context, $user->id);
	$rolesname = array();
	foreach ($roles as $role){
		$rolesname[] = $role->shortname;
	}

	if (in_array('admin',$rolesname) || in_array('coursecreator',$rolesname)){
		return "Administrator";
	}

	if (in_array('editingteacher',$rolesname) || in_array('teacher',$rolesname)){
		return 'Instructor';
	}

	return "Student";

}

/**
 * @TODO: doc this function
 */
function basiclti_get_type_config($typeid){
	global $DB;

	$typeconfig = array();
	$configs = $DB->get_records('basiclti_types_config', array('typeid' => $typeid));
	if (!empty($configs)){
		foreach ($configs as $config){
			$typeconfig[$config->name] = $config->value;
		}
	}
	return $typeconfig;
}


/**
 * @TODO: doc this function
 */
function basiclti_filter_get_types(){
	global $DB;
	return $DB->get_records('basiclti_types');
}

/**
 * @TODO: doc this function
 */
function basiclti_filter_print_types(){
global $CFG, $USER;

	$types = basiclti_filter_get_types();
	if (!empty($types)){
		echo '<ul>';
		foreach ($types as $type){
			echo '<li>'.
			$type->name.
			'<span class=commands>'.
			'<a class="editing_update" href="typessettings.php?action=update&amp;id='.$type->id.'&amp;sesskey='.$USER->sesskey.'" title="Update">'.
			'<img class="iconsmall" alt="Update" src="'.$CFG->wwwroot.'/pix/t/edit.gif"/>'.
			'</a>'.
			'<a class="editing_delete" href="typessettings.php?action=delete&amp;id='.$type->id.'&amp;sesskey='.$USER->sesskey.'" title="Delete">'.
			'<img class="iconsmall" alt="Delete" src="'.$CFG->wwwroot.'/pix/t/delete.gif"/>'.
			'</a>'.
			'</span>'.
			'</li>';
		}
		echo '</ul>';
	} else {
		echo get_string('notypes', 'basiclti');
	}
}

/**
 * @TODO: doc this function
 */
function basiclti_delete_type($id){
	global $DB;

	$DB->delete_records('basiclti_types', array('id' => $id));
	$DB->delete_records('basiclti_types_config', array('typeid' => $id));
}

/**
 * @TODO: doc this function
 */
function basiclti_get_type_type_config($id){
	global $DB;

	$basicltitype = $DB->get_record('basiclti_types', array('id' => $id));
	$config = basiclti_get_type_config($id);

	$type = new StdClass();
	$type->lti_typename = $basicltitype->name;
	if (isset($config['toolurl'])){
		$type->lti_toolurl = $config['toolurl'];
	}
	if (isset($config['password'])){
		$type->lti_password = $config['password'];
	}
	if (isset($config['resourceurl'])){
		$type->lti_resourceurl = $config['resourceurl'];
	}
	if (isset($config['preferwidget'])){
		$type->lti_preferwidget = $config['preferwidget'];
	}
	if (isset($config['preferheight'])){
		$type->lti_preferheight = $config['preferheight'];
	}
	if (isset($config['preferwidth'])){
		$type->lti_preferwidth = $config['preferwidth'];
	}
	return $type;
}

/**
 * @TODO: doc this function
 */
function basiclti_add_config($config){
	global $DB;

	return $DB->insert_record('basiclti_types_config', $config);
}

/**
 * @TODO: doc this function
 */
function basiclti_update_config($config){
	global $DB;

	$return = true;
	if ($old = $DB->get_record('basiclti_types_config',
					array('typeid' => $config->typeid, 'name' => $config->name))){
		$config->id = $old->id;
		$return = $DB->update_record('basiclti_types_config', $config);
	} else {
		$return = $DB->insert_record('basiclti_types_config', $config);
	}
	return $return;
}
?>